home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / bin / 4dview / 4dstuff.C < prev    next >
C/C++ Source or Header  |  1993-08-18  |  15KB  |  714 lines

  1. #include "4dstuff.h"
  2. extern "C" {
  3. #include "ooglwrap.h"
  4. }
  5.  
  6. /* Clipper 1.0 */
  7. /* by Daeron */
  8.  
  9. double WMAX=0.0,WMIN=0.0;
  10.  
  11. /* ends of color spectrum used for 4th coordinate */
  12. float R_0=0, G_0=0, B_0=1;
  13. float R_1=1, G_1=0, B_1=0;
  14.  
  15. /*****************************************************************************/
  16.  
  17. void err_msg(char *errmsg)
  18. {
  19.  fprintf(stderr,"%s\n",errmsg);
  20. }
  21.  
  22. /*****************************************************************************/
  23.  
  24. /* Class initializers */
  25.  
  26. vertex::vertex()
  27. {
  28.  x=0.0;y=0.0;z=0.0;w=0.0;r=0.5;g=0.5;b=0.5;a=0.5;clip=0;num=0;next=NULL;
  29. }
  30.  
  31. vertex_list::vertex_list()
  32. {
  33.  numvtx=0;head=NULL;
  34.  colorscheme = 0;
  35.  coloron = 0;
  36.  projection=1;
  37. }
  38.  
  39. pvtx::pvtx()
  40. {
  41.  num=0;next=NULL;
  42. }
  43.  
  44. polyvtx_list::polyvtx_list()
  45. {
  46.  numvtx=0;head=NULL;
  47. }
  48.  
  49. poly::poly()
  50. {
  51.  numvtx=0;me=NULL;next=NULL;clipped=0;
  52. }
  53.  
  54. poly_list::poly_list()
  55. {
  56.  numpoly=0;head=NULL;
  57. }
  58.  
  59. /*****************************************************************************/
  60.  
  61. void vertex_list::clip_vertex(double a1, double b1, double c1,
  62.                 double d1, double e1, int side1)
  63. {
  64.  double tmp,tmp2;
  65.  
  66.  side=side1;
  67.  a=a1;b=b1;c=c1;d=d1;e=e1;
  68.  point = head;
  69.  while (point!=NULL)
  70.  {
  71.   tmp = a*(point->x) + b*(point->y) + c*(point->z) + d*(point->w);
  72.   tmp2 = tmp-e;
  73.   if (tmp2<0) tmp2 = tmp2*(-1.0);
  74.   if (tmp2>.00001)
  75.   {
  76.    if ((tmp<e)&&(side==1))
  77.     point->clip=1;
  78.    else
  79.    if ((tmp>e)&&(side==0))
  80.     point->clip=1;
  81.   }
  82.   point = point->next;
  83.  }
  84. }
  85.  
  86. /*****************************************************************************/
  87.  
  88. void vertex_list::put_in_array(vertex **vertex_set)
  89. {
  90.   int count=0;
  91.  
  92.   point = head;
  93.   while (point!=NULL)
  94.   {
  95.    vertex_set[count] = point;
  96.    point->num = count;
  97.    point=point->next;
  98.    count++;
  99.   }
  100.   numvtx = count;
  101. }
  102.  
  103. /*****************************************************************************/
  104.  
  105. vertex *vertex_list::add_vertex(double x, double y, double z, double w)
  106. {
  107.   vertex *temp = head;
  108.  
  109.   head = new vertex;
  110.   head->next = temp;
  111.   head->x = x; head->y = y; head->z = z; head->w = w;
  112.   head->clip = 0;
  113.   return (head);
  114. }
  115.  
  116. /*****************************************************************************/
  117.  
  118. int polyvtx_list::find_unclipped_vertex(vertex **vertex_set)
  119. {
  120.  pvtx *temp = head;
  121.  int brk=0;
  122.  
  123.  point = head;
  124.  do
  125.  {
  126.   brk = vertex_set[point->num]->clip;
  127.   if (brk)
  128.    point=point->next;
  129.  } while ((brk)&&(point!=temp));
  130.  if ((point==temp)&&(brk)) return (1);
  131.  head = point;
  132.  return (0);
  133. }
  134.  
  135. /*****************************************************************************/
  136.  
  137. int polyvtx_list::clip_each_vertex(vertex_list *vtxl, vertex **vertex_set)
  138. {
  139.  pvtx *temp, *next, *last;
  140.  double t,t1,t2,nx,ny,nz,nw;
  141.  double x1,y1,z1,w1;
  142.  double x2,y2,z2,w2;
  143.  
  144.  double a = vtxl->a, b = vtxl->b, c = vtxl->c, d = vtxl->d, e = vtxl->e;
  145.  last = head;
  146.  point = head;
  147.  point->me = vertex_set[point->num];
  148.  do 
  149.  {
  150.   next = point->next;
  151.   next->me = vertex_set[next->num];
  152.   x1 = vertex_set[point->num]->x; y1 = vertex_set[point->num]->y;
  153.   z1 = vertex_set[point->num]->z; w1 = vertex_set[point->num]->w;
  154.   x2 = vertex_set[next->num]->x; y2 = vertex_set[next->num]->y;
  155.   z2 = vertex_set[next->num]->z; w2 = vertex_set[next->num]->w;
  156.   if ((!(vertex_set[point->num]->clip))&&(vertex_set[next->num]->clip))
  157.   {
  158.    t1 = (e - a*x1 - b*y1 - c*z1 - d*w1);
  159.    t2 = a*(x2 - x1) + b*(y2 - y1) + c*(z2 - z1) + d*(w2 - w1);
  160.    if (t2!=0.0)
  161.    {
  162.     t = t1 / t2;
  163.     nx = x1 + t*(x2 - x1); ny = y1 + t*(y2 - y1); nz = z1 + t*(z2 - z1);
  164.     nw = w1 + t*(w2 - w1);
  165.     temp = new pvtx;
  166.     temp->me = vtxl->add_vertex(nx,ny,nz,nw);
  167.     numvtx++;
  168.     temp->next = next;
  169.     point->next = temp;
  170.     last = temp;
  171.     point = next;
  172.     next = point->next;
  173.    }
  174.    else
  175.    {
  176.     last = point;
  177.     point = next;
  178.     next = point->next;
  179.     vertex_set[point->num]->clip = 0;
  180.     printf("unclip\n");
  181.    }
  182.   }
  183.   else if ((vertex_set[point->num]->clip)&&(vertex_set[next->num]->clip))
  184.   {
  185.    /*t2 = a*(x2-x1) + b*(y2-y1) + c*(z2-z1) + d*(w2-w1);
  186.    if (t2!=0.0)
  187.    {*/
  188.     last->next = next;
  189.     delete point;
  190.     numvtx--;
  191.     point = next;
  192.     next = point->next;
  193.    /*}
  194.    else
  195.    {
  196.     printf("AAAA!\n");
  197.     last = point;
  198.     point = next;
  199.     next = point->next;
  200.    }*/
  201.   }
  202.   else if ((vertex_set[point->num]->clip)&&(!(vertex_set[next->num]->clip)))
  203.   {
  204.    t1 = (e - a*x1 - b*y1 - c*z1 - d*w1);
  205.    t2 = a*(x2 - x1) + b*(y2 - y1) + c*(z2 - z1) + d*(w2 - w1);
  206.    if (t2!=0.0)
  207.    {
  208.     t = t1/t2;
  209.     nx = x1 + t*(x2 - x1); ny = y1 + t*(y2 - y1); nz = z1 + t*(z2 - z1);
  210.     nw = w1 + t*(w2 - w1);
  211.     temp = new pvtx;
  212.     temp->me = vtxl->add_vertex(nx,ny,nz,nw);
  213.     temp->next = next;
  214.     last->next = temp;
  215.     delete point;
  216.     last = temp;
  217.     point = next;
  218.     next = point->next;
  219.    }
  220.    else
  221.    {
  222.     last = point;
  223.     vertex_set[point->num]->clip = 0;
  224.     point = next;
  225.     next = point->next;
  226.     printf("unclip2\n");
  227.    }
  228.   }
  229.   else
  230.   {
  231.    last=point;
  232.    point=next;
  233.    next=point->next;
  234.   }
  235.  } while (point!=head);
  236.  return numvtx;
  237. }
  238.  
  239. /*****************************************************************************/
  240.  
  241. void poly::clip_poly(vertex_list *vtxl, vertex **vertex_set)
  242. {
  243.  
  244.   clipped = me->find_unclipped_vertex(vertex_set);
  245.   if (clipped) return;
  246.   numvtx = me->clip_each_vertex(vtxl,vertex_set);
  247. }
  248.  
  249. /*****************************************************************************/
  250.  
  251. void poly_list::clip_polys(vertex_list *vtxl)
  252. {
  253.  
  254.  int count=0;
  255.  vertex **vertex_set;
  256.  
  257.  vertex_set = new vertex*[vtxl->numvtx];
  258.  vtxl->put_in_array(vertex_set);
  259.  point = head;
  260.  while (point!=NULL)
  261.  {
  262.   point->clip_poly(vtxl,vertex_set);
  263.   point=point->next;
  264.  }
  265.  delete vertex_set;
  266. }
  267.  
  268. /*****************************************************************************/
  269.  
  270. void vertex::read_vertex4d(int count, FILE *fin, int coloron)
  271. {
  272.  char nxtc;
  273.  r = 0.5; g = 0.5; b = 0.5; a = 1.0;
  274. /* fprintf(stderr,"reading 4vertices - color = %d\n",coloron);*/
  275.  if (coloron)
  276.    fscanf(fin,"%lf %lf %lf %lf  %lf %lf %lf %lf",&x,&y,&z,&w,&r,&g,&b,&a);
  277.  else
  278.    fscanf(fin,"%lf %lf %lf %lf",&x,&y,&z,&w);
  279. /* fprintf(stderr,"%lf %lf %lf %lf -> %lf %lf %lf %lf\n",x,y,z,w,r,g,b,a);*/
  280.  num=count;
  281.  if (x<WMIN) WMIN=x;
  282.  if (y<WMIN) WMIN=y;
  283.  if (z<WMIN) WMIN=z;
  284.  if (w<WMIN) WMIN=w;
  285.  if (x>WMAX) WMAX=x;
  286.  if (y>WMAX) WMAX=y;
  287.  if (z>WMAX) WMAX=z;
  288.  if (w>WMAX) WMAX=w;
  289.  nxtc = ' ';
  290.  while (nxtc!='\n')
  291.   nxtc = (char)fgetc(fin);
  292. }
  293.  
  294. /*****************************************************************************/
  295.  
  296. void vertex::read_vertex(int count, FILE *fin, int coloron)
  297. {
  298.  char nxtc;
  299.  r = 0.5; g = 0.5; b = 0.5; a = 1.0;
  300. /* fprintf(stderr,"reading 3vertices - color = %d\n",coloron);*/
  301.  if (coloron)
  302.    fscanf(fin,"%lf %lf %lf  %lf %lf %lf %lf",&x,&y,&z,&r,&g,&b,&a);
  303.  else
  304.    fscanf(fin,"%lf %lf %lf",&x,&y,&z);
  305.  w = 1.0;
  306. /* fprintf(stderr,"%lf %lf %lf -> %lf %lf %lf %lf\n",x,y,z,r,g,b,a);*/
  307.  num=count;
  308.  if (x<WMIN) WMIN=x;
  309.  if (y<WMIN) WMIN=y;
  310.  if (z<WMIN) WMIN=z;
  311.  if (w<WMIN) WMIN=w;
  312.  if (x>WMAX) WMAX=x;
  313.  if (y>WMAX) WMAX=y;
  314.  if (z>WMAX) WMAX=z;
  315.  if (w>WMAX) WMAX=w;
  316.  nxtc = ' ';
  317.  while (nxtc!='\n')
  318.   nxtc = (char)fgetc(fin);
  319. }
  320.  
  321. /*****************************************************************************/
  322.  
  323. void vertex_list::read_vertices(int numvx, FILE *fin)
  324. {
  325.  int count;
  326.  vertex *old;
  327.  
  328.  WMAX=0.0;
  329.  WMIN=0.0;
  330.  numvtx = numvx;
  331.  point = new vertex;
  332.  if (vtype==4)
  333.   point->read_vertex4d(0,fin,coloron);
  334.  else
  335.   point->read_vertex(0,fin,coloron);
  336.  head = point;
  337.  old = point;
  338.  for (count=1;count<numvtx;count++)
  339.  {
  340.   point = new vertex;
  341.   old->next = point;
  342.  if (vtype==4)
  343.   point->read_vertex4d(count,fin,coloron);
  344.  else
  345.   point->read_vertex(count,fin,coloron);
  346.   old = point;
  347.  }
  348.  point->next = NULL;
  349. }
  350.  
  351. /*****************************************************************************/
  352.  
  353. void pvtx::read_pvtx(FILE *fin)
  354. {
  355.  fscanf(fin,"%d",&num);
  356. }
  357.  
  358. /*****************************************************************************/
  359.  
  360. void polyvtx_list::read_polyvtx(int numvx, FILE *fin)
  361. {
  362.  int count;
  363.  pvtx *old;
  364.  char temp;
  365.  
  366.  numvtx = numvx;
  367.  point = new pvtx;
  368.  point->read_pvtx(fin);
  369.  head = point;
  370.  old = point;
  371.  for (count=1;count<numvtx;count++)
  372.  {
  373.   point = new pvtx;
  374.   old->next = point;
  375.   point->read_pvtx(fin);
  376.   old = point;
  377.  }
  378.  point->next = head;
  379.  fscanf(fin,"%c",&temp);
  380.  while ((temp!='\n')&&(!feof(fin)))
  381.   fscanf(fin,"%c",&temp);
  382. }
  383.  
  384. /*****************************************************************************/
  385.  
  386. void poly::read_poly(FILE *fin)
  387. {
  388.  fscanf(fin,"%d ",&numvtx);
  389.  me = new polyvtx_list;
  390.  me->read_polyvtx(numvtx,fin);
  391. }
  392.  
  393.  
  394. /*****************************************************************************/
  395.  
  396. void poly_list::read_polys(int numpl, FILE *fin)
  397. {
  398.  int count;
  399.  poly *old;
  400.  
  401.  numpoly = numpl;
  402.  point = new poly;
  403.  point->read_poly(fin);
  404.  head = point;
  405.  old = point;
  406.  for (count=1;count<numpoly;count++)
  407.  {
  408.   point = new poly;
  409.   old->next = point;
  410.   point->read_poly(fin);
  411.   old = point;
  412.  }
  413.  point->next = NULL;
  414. }
  415.  
  416. /*****************************************************************************/
  417.  
  418. void vertex_list::refresh_vertex_list()
  419. {
  420.  int count = 0;
  421.  vertex *prev;
  422.  
  423.  point = head;
  424.  if (point!=NULL)
  425.   while ((point->clip)&&(point->next!=NULL))
  426.   {
  427.    prev = point;
  428.    point = point->next;
  429.    delete prev;
  430.    head = point;
  431.   }
  432.  if (point!=NULL)
  433.  {
  434.  point->num = count;
  435.  count++;
  436.  prev = point;
  437.  point = point->next;
  438.  }
  439.  while (point!=NULL)
  440.  {
  441.   if (!(point->clip))
  442.   {
  443.    prev = point;
  444.    point->num = count;
  445.    count++;
  446.   }
  447.   else
  448.   {
  449.    prev->next = point->next;
  450.    delete point;
  451.    point = prev;
  452.   }
  453.   point=point->next;
  454.  }
  455.  numvtx=count;
  456. }
  457.  
  458. /*****************************************************************************/
  459.  
  460. void poly_list::refresh_poly_list()
  461. {
  462.  int count = 0;
  463.  poly *prev;
  464.  
  465.  point = head;
  466.  if (point!=NULL)
  467.   while ((point->clipped)&&(point->next!=NULL))
  468.   {
  469.    prev = point;
  470.    point = point->next;
  471.    delete prev;
  472.    head = point;
  473.   }
  474.  count++;
  475.  if (point==NULL) count=0;
  476.  prev = point;
  477.  point = point->next;
  478.  
  479.  while (point!=NULL)
  480.  {
  481.   if (!(point->clipped))
  482.   {
  483.    prev = point;
  484.    count++;
  485.   }
  486.   else
  487.   {
  488.    prev->next = point->next;
  489.    delete point;
  490.    point = prev;
  491.   }
  492.   point=point->next;
  493.  }
  494.  numpoly=count;
  495. }
  496. /*
  497. void poly_list::refresh_poly_list()
  498. {
  499.  int count = 0;
  500.  
  501.  point = head;
  502.  while (point!=NULL)
  503.  {
  504.   if (!(point->clipped))
  505.    count++;
  506.   point=point->next;
  507.  }
  508.  numpoly=count;
  509. }*/
  510.  
  511. /*****************************************************************************/
  512.  
  513. int load_off_file(poly_list *polyhedron, vertex_list *polyvertex,
  514.         char *name, char *filename)
  515. {
  516.  FILE *fin,*fout;
  517.  
  518.  char toss[256];
  519.  char nxtc;
  520.  int vrtx,face,edge;
  521.  
  522.  
  523.  system("rm -f /tmp/xx4dtmp");
  524.  if (!(fin=fopen(name,"r")))
  525.  {
  526.   err_msg("Could not open input file.");
  527.   return (0);
  528.  }
  529.  if (!(fout=fopen("/tmp/xx4dtmp","w")))
  530.  {
  531.   err_msg("Couldn\'t use tmp directory.\n");
  532.   return (0);
  533.  }
  534.  fclose(fout); fclose(fin);
  535.  CCWrap(name,"/tmp/xx4dtmp");
  536.  
  537.  if (!(fin=fopen("/tmp/xx4dtmp","r")))
  538.  {
  539.   err_msg("Couldn\'t use tmp directory.\n");
  540.   return (0);
  541.  }
  542.  nxtc = ' ';
  543.  while (nxtc!='=')
  544.   nxtc = fgetc(fin);
  545.  fgetc(fin);
  546.  nxtc = fgetc(fin);
  547.  if (nxtc!='4')
  548.   polyvertex->vtype=3;
  549.  else
  550.   polyvertex->vtype=4;
  551.  
  552.  fscanf(fin,"%s\n",toss);
  553.  if ((toss[0] == 'C') || (nxtc == 'C'))
  554.    polyvertex->coloron = 1;
  555.  else
  556.    polyvertex->coloron = 0;
  557.  if (toss[0] == '4')
  558.    polyvertex->vtype = 4;
  559. /*
  560.  fprintf(stderr,
  561.     "File type: %d%s - %d\n",polyvertex->vtype,toss,polyvertex->coloron);
  562. */
  563.  sprintf(filename,"%s",name);
  564.  fscanf(fin,"%d %d %d\n\n",&vrtx,&face,&edge);
  565.  if ((vrtx==0)||(face==0)  /*||(edge==0)*/)
  566.  {
  567.   //err_msg("Bad parameters.");
  568.   return (0);
  569.  }
  570.  polyvertex->read_vertices(vrtx,fin);
  571.  polyhedron->read_polys(face,fin);
  572.  system("rm -f /tmp/xx4dtmp");
  573.  return(1);
  574. }
  575.  
  576. /*****************************************************************************/
  577.  
  578. void vertex_list::write_vertices(FILE *fout)
  579. {
  580.  point=head;
  581.  while(point!=NULL)
  582.  {
  583.   if (!(point->clip))
  584.    fprintf(fout,"\t%lf %lf %lf %lf\n",point->x,point->y,point->z,point->w);
  585.   point=point->next;
  586.  }
  587. }
  588.  
  589. /*****************************************************************************/
  590.  
  591. void vertex_list::setproj(int proj)
  592. {
  593.  projection = proj;
  594. }
  595.  
  596. /*****************************************************************************/
  597.  
  598. void vertex_list::write_vertices3d(FILE *fout, float T[4][4], clip_plane *clipper)
  599. {
  600.  float x,y,z,w;
  601.  float xo,yo,zo,wo;
  602.  float rd,gr,bl,wrng;
  603.  float depth;
  604.  
  605.  wrng=(float)(WMAX-WMIN);
  606.  
  607.  /* transform, color, and ship out the vertices */
  608.  point=head;
  609.  while(point!=NULL)
  610.  {
  611.   if (!(point->clip))
  612.   {
  613.    x=(float)point->x,y=(float)point->y,z=(float)point->z,
  614.         w=(float)point->w;
  615.    xo = x*T[0][0] + y*T[0][1] + z*T[0][2] + w*T[0][3];
  616.    yo = x*T[1][0] + y*T[1][1] + z*T[1][2] + w*T[1][3];
  617.    zo = x*T[2][0] + y*T[2][1] + z*T[2][2] + w*T[2][3];
  618.    wo = x*T[3][0] + y*T[3][1] + z*T[3][2] + w*T[3][3];
  619.    rd = (wo-WMIN)/wrng;
  620.    bl = 1.0-rd;
  621.    if (projection)
  622.    {
  623.     /* perspective distortion */
  624.     xo = xo/(rd*2.0+1.0);
  625.     yo = yo/(rd*2.0+1.0);
  626.     zo = zo/(rd*2.0+1.0);
  627.    }
  628.    if (colorscheme)
  629.    {
  630.      gr = 0.0;
  631.      if (rd<0.0) rd=0.0;
  632.      if (rd>1.0) rd=1.0;
  633.      if (bl<0.0) bl=0.0;
  634.      if (bl>1.0) bl=1.0;
  635.    }
  636.    else
  637.    {
  638.      rd=(float)point->r;
  639.      gr=(float)point->g;
  640.      bl=(float)point->b;
  641.    }
  642.  
  643.    depth = x*(float)clipper->ax + y*(float)clipper->by +
  644.         z*(float)clipper->cz + w*(float)clipper->dw;
  645.    if ((depth > ((float)clipper->depth)+.00001)) {rd=1.0;gr=1.0;bl=1.0;}
  646.  
  647.    fprintf(fout,"%f %f %f\t%f %f %f 1\n", xo,yo,zo,rd,gr,bl);
  648.   }
  649.   point=point->next;
  650.  }
  651. }
  652.  
  653. /*****************************************************************************/
  654.  
  655. void polyvtx_list::write_polyvtx(FILE *fout)
  656. {
  657.  pvtx *temp;
  658.  
  659.  temp=head;
  660.  point=head;
  661.  fprintf(fout,"\t%d",numvtx);
  662.  do
  663.  {
  664.   fprintf(fout," %d",point->me->num);
  665.   point->num = point->me->num;
  666.   point=point->next;
  667.  } while (point!=temp);
  668.  fprintf(fout,"\n");
  669. }
  670.  
  671. /*****************************************************************************/
  672.  
  673. void poly_list::write_polys(FILE *fout)
  674. {
  675.  point=head;
  676.  while(point!=NULL)
  677.  {
  678.   if (!(point->clipped))
  679.     point->me->write_polyvtx(fout);
  680.   point=point->next;
  681.  }
  682. }
  683.  
  684. /*****************************************************************************/
  685.  
  686. void store_off_file(poly_list *polyhedron, vertex_list *polyvertex,
  687.         char *storename)
  688. {
  689.  FILE *fout = NULL;
  690.  
  691.  storename = NULL;
  692.  //if (!(fout=fopen(storename,"w"))) err_msg("Couldn\'t save to output file.\n");
  693.  fprintf(fout,"4OFF\n %d %d 1\n",polyvertex->numvtx,polyhedron->numpoly);
  694.  polyvertex->write_vertices(fout);
  695.  polyhedron->write_polys(fout);
  696.  
  697. }
  698.  
  699. /*****************************************************************************/
  700.  
  701. clip_plane::clip_plane()
  702.  
  703. {
  704.  ax=0;by=0;cz=0;dw=0;depth=10000.0;
  705. }
  706.  
  707. /*****************************************************************************/
  708.  
  709. void sliderval(float *a, float *b)
  710. {
  711.   *a = (float)WMIN;
  712.   *b = (float)WMAX;
  713. }
  714.